using System;
using System.Data;
using System.Data.SqlClient;
using Comp = System.ComponentModel;
using Col = System.Collections;
using Generic = System.Collections.Generic;

namespace sdf.Code
{
	/// <summary>
	/// Generically wraps entity objects (or whatever else is thrown at it) into List<T>
	/// </summary>
	/// <typeparam name="T">IEntity type</typeparam>
	public class EntityTList<T> where T : class, IEntity, new()
	{
		//fire up  a generic list
		private readonly Generic.List<T> _EntityList = new Generic.List<T>();

		/// <summary>
		/// Expose general IList interface to collection -- objects that can be individually accessed by index. 
		/// IList used to provide a simplied list of methods and properties to work with.
		/// </summary>
		public Generic.IList<T> IList
		{
			get { return _EntityList; }
		}

		/// <summary>
		/// Expose IEnumerable, which supports a simple iteration over a collection of a specified type
		/// IEnumerable used to provide a simplied list of methods and properties to work with with.
		/// </summary>
		public Generic.IEnumerable<T> IEnumerable
		{
			get { return _EntityList; }
		}

		/// <summary>
		///	Creates and Fill an CLib.EntityTList<(Membership> with all rows from a reader
		/// </summary>
		/// <returns>populated generic list</returns>
		/// <param name="reader">Open reader object</param>
		public void FillList(SqlDataReader reader)
		{
			FillList(reader, 0, -1); 
		}

		/// <summary>
		///	Creates and Fill an CLib.EntityTList<(Membership> from a reader, with paging support
		/// </summary>
		/// <returns>populated generic list</returns>
		/// <param name="reader">Open reader object</param>
		/// <param name="iStartIndex">Record index at which to start populating list (base 0)</param>
		/// <param name="iPageLength">Number of records to return (-1 = all)</param>
		public void FillList(SqlDataReader reader, int iStartIndex, int iPageLength) 
		{
			//if nothing to read, return
			if (!reader.HasRows)
			{
				return;
			}

			//-1 page length = all
			iPageLength = (iPageLength == -1) ? int.MaxValue : iPageLength;

			//start index of 1 should really be 0
			iStartIndex = (iStartIndex == 1) ? 0 : iStartIndex;

			// advance to the start index
			for (int i = 0; i < iStartIndex; i++)
			{
				//if reached end before start index, return empty list
				if (!reader.Read())
					return;
			}

			// add entities to list, up to page length
			for (int i = 0; i < iPageLength; i++)
			{
				//if at end of list
				if (!reader.Read())
					break; //

				//create and populate entity. Validate ordinals on first pass (i == 0)
				T entity = new T();
				entity.refreshEntity(reader, (i == 0));

				//add to list
				_EntityList.Add(entity);
			}
		}
	}
}